package com.partvoyage.client.mvp2.view.infoGeneral;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.partvoyage.client.mvp2.event.LoadDataInformationGeneralEvent;
import com.partvoyage.client.mvp2.event.LoadDataInformationGeneralEvent.TYPE_INFORMATION_GENERAL;
import com.partvoyage.client.mvp2.framework.MVPDisplay;
import com.partvoyage.client.mvp2.framework.MVPPresenter;
import com.partvoyage.client.service.calendrier.CalendarService;
import com.partvoyage.client.service.calendrier.CalendarServiceAsync;
import com.partvoyage.client.service.infopoint.InfoPointService;
import com.partvoyage.client.service.infopoint.InfoPointServiceAsync;
import com.partvoyage.client.service.projet.ProjetBean;
import com.partvoyage.client.service.projet.ProjetService;
import com.partvoyage.client.service.projet.ProjetServiceAsync;
import com.partvoyage.client.sessionClient.SessionClient;
import com.partvoyage.shared.InfoPointBean;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.RecordList;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.calendar.Calendar;
import com.smartgwt.client.widgets.calendar.CalendarEvent;
import com.smartgwt.client.widgets.calendar.events.DayBodyClickEvent;
import com.smartgwt.client.widgets.calendar.events.DayBodyClickHandler;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.events.HasClickHandlers;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.layout.HLayout;

public class InformationGeneralPresenter extends
		MVPPresenter<InformationGeneralPresenter.Display> {
	protected final InfoPointServiceAsync infoService = GWT
			.create(InfoPointService.class);
	private final CalendarServiceAsync calendarService = GWT
			.create(CalendarService.class);
	private final ProjetServiceAsync projetService = GWT
			.create(ProjetService.class);

	public interface Display extends MVPDisplay {
		HasClickHandlers getValidationNomProjet();

		HasClickHandlers getValidationCommentaire();

		HasClickHandlers getAnimationTitreFlow();

		void setNomProjetText(String nomProjet);

		void setCoutGlobalText(String coutGlobal);

		void setCommentaireText(String commentaireText);

		DynamicForm getCommentaireForm();

		DynamicForm getNomProjetForm();

		void setDateDepart(String dateDepart);

		void setDateArrive(String dateArrive);

		Calendar getCalendar();

		DataSource getEventDS();

		void setEventDS(DataSource eventDS);

		HLayout getCalendrierLayout();
	}

	public InformationGeneralPresenter(final Display display,
			final HandlerManager eventBus) {
		super(display, eventBus);
		bind();
	}

	/**
	 * Lie le bouton send à l'action ....
	 */
	protected void bind() {

		display.getValidationNomProjet().addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				ProjetBean projetBean = SessionClient.getInstance()
						.getProjetBeanCourant();
				projetBean.setNom((String) display.getNomProjetForm()
						.getField("nomProjetTextItem").getValue());
				projetService.update(projetBean,
						new AsyncCallback<ProjetBean>() {

							@Override
							public void onFailure(Throwable caught) {
								// TODO Auto-generated method stub

							}

							@Override
							public void onSuccess(ProjetBean result) {
								// TODO Auto-generated method stub

							}

						});
			}
		});
		display.getValidationCommentaire().addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				ProjetBean projetBean = SessionClient.getInstance()
						.getProjetBeanCourant();
				projetBean.setCommentaire((String) display.getCommentaireForm()
						.getField("commentaireTextItem").getValue());
				projetService.update(projetBean,
						new AsyncCallback<ProjetBean>() {

							@Override
							public void onFailure(Throwable caught) {
								// TODO Auto-generated method stub

							}

							@Override
							public void onSuccess(ProjetBean result) {
								// TODO Auto-generated method stub

							}

						});
			}
		});
		display.getAnimationTitreFlow().addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				// creer getter setter
				// if (estEtendu) {
				//
				// animationTitreFlow.animateResize(
				// animationTitreFlow.getWidth(),
				// hauteurOriginialDuTitre);
				//
				// estEtendu = false;
				// animationTitreFlow.setContents(titreTailleNormal);
				// } else {
				//
				// animationTitreFlow.animateResize(
				// animationTitreFlow.getWidth(), hauteurFinalDuTitre);
				// estEtendu = true;
				// animationTitreFlow
				// .setContents(titreTailleNormal
				// +
				// "<br><ul><li>Nom du projet: BLABLABLA</li><li>Date de départ du voyage: BLABLABLA</li><li>Date d'arrivé: BLABLABLA</li><li>Budget total: BLABLABLA</li><li>Commentaire: BLABLABLA</li></ul>");
				// }

			}
		});
		display.getCalendar().addDayBodyClickHandler(new DayBodyClickHandler() {
			public void onDayBodyClick(DayBodyClickEvent event) {
				String nameStr = "";
				CalendarEvent[] events = event.getEvents();
				if (events.length == 0) {
					nameStr = "No events";
				} else {
					for (CalendarEvent calEvent : events) {
						nameStr += calEvent.getName() + " "
								+ calEvent.getDescription() + "<br/>";
					}
				}
				SC.say(nameStr);
			}
		});

	}

	@Override
	public void go(final HasWidgets container) {

	}

	public void go(HLayout container) {
		// container.clear();
		container.addChild(display.asWidget());

	}

	@Override
	protected void registerHandler() {
		// gestion des données des informations du point courant
		eventBus.addHandler(
				LoadDataInformationGeneralEvent.TYPE,
				new LoadDataInformationGeneralEvent.LoadDataInformationGeneralEventHandler() {

					@Override
					public void onLoadDataInformationGeneral(
							LoadDataInformationGeneralEvent event) {
						ProjetBean projetBean = SessionClient.getInstance()
								.getProjetBeanCourant();
						if (TYPE_INFORMATION_GENERAL.TYPE_ALL.equals(event
								.getType())) {
							// nom du projet
							display.setNomProjetText(projetBean.getNom());
							// commentaire
							display.setCommentaireText(projetBean
									.getCommentaire());
							// cout global
							loadCoutTotal(projetBean);
							reloadQuand(projetBean);
						} else if (TYPE_INFORMATION_GENERAL.TYPE_COUT
								.equals(event

								.getType())) {
							// cout global
							loadCoutTotal(projetBean);
						} else if (TYPE_INFORMATION_GENERAL.TYPE_NETTOYAGE_INFO_POINT
								.equals(event.getType())) {
							display.setCoutGlobalText(null);
							RecordList recordList = display.getCalendar()
									.getRecordList();
							Record[] array = recordList.toArray();
							for (Record record : array) {
								CalendarEvent calendarEvent = new CalendarEvent();
								calendarEvent.setAttribute("eventId",
										String.valueOf(record
												.getAttribute("eventId")));
								// calendarEvent.setAttribute("markerId", String
								// .valueOf(infoPointBean.getMarkerId()));
								display.getCalendar()
										.removeEvent(calendarEvent);

								display.getCalendar().markForRedraw();
							}
						} else if (TYPE_INFORMATION_GENERAL.TYPE_QUAND
								.equals(event.getType())) {
							loadQuand(event.getInfoPointBean());
						} else if (TYPE_INFORMATION_GENERAL.TYPE_NETTOYAGE
								.equals(event.getType())) {
							display.setNomProjetText("Defaut");
							display.setCommentaireText(null);
							display.setCoutGlobalText(null);
							display.setDateDepart(null);
							display.setDateArrive(null);
							display.getCalendar().clear();
							// RecordList recordList = display
							// .getCalendar().getRecordList();
							// Record[] array =
							// recordList.toArray();
							// for (Record record : array) {
							// CalendarEvent calendarEvent = new
							// CalendarEvent();
							// calendarEvent.setAttribute("eventId",
							// String.valueOf(record
							// .getAttribute("eventId")));
							// // calendarEvent.setAttribute("markerId", String
							// // .valueOf(infoPointBean.getMarkerId()));
							// display.getCalendar()
							// .removeEvent(calendarEvent);
							//
							// display.getCalendar().markForRedraw();
							// }
						}
					}

					private void loadCoutTotal(ProjetBean projetBean) {
						projetService.getCoutTotal(projetBean.getProjetId(),
								new AsyncCallback<Double>() {

									@Override
									public void onSuccess(Double coutGlobal) {
										display.setCoutGlobalText(String
												.valueOf(coutGlobal));

									}

									@Override
									public void onFailure(Throwable caught) {
										// TODO Auto-generated method stub

									}
								});
					}

					private void loadQuand(InfoPointBean infoPointBean) {

						Record record = getRecord(infoPointBean.getMarkerId());
						if (record == null) {
							System.out
									.println("[client] création d'un record avec markerID : "
											+ infoPointBean.getMarkerId()
											+ ", ou "
											+ infoPointBean.getOu()
											+ ", quand "
											+ infoPointBean.getQuand());
							// on associe à l'event l'id du
							// marker
							Map<String, String> map = new HashMap<String, String>();
							map.put("markerId",
									String.valueOf(infoPointBean.getMarkerId()));
							// création de l'evenement
							if (infoPointBean.getQuand() != null) {
								display.getCalendar().addEvent(
										infoPointBean.getQuand(),
										infoPointBean.getQuand(),
										infoPointBean.getOu(),
										infoPointBean.getCommentaire(), map);
								display.getCalendar().markForRedraw();
							}
						} else {

							// TODO trouver un moyen plus
							// élégant

							// création du calendarevent
							// pour la clé
							if (infoPointBean.getQuand() != null) {
								System.out.println("[client] mise à jour d'un record "
										+ String.valueOf(record
												.getAttribute("eventId"))
										+ "avec markerID : "
										+ infoPointBean.getMarkerId()
										+ ", ou "
										+ infoPointBean.getOu()
										+ ", quand "
										+ infoPointBean.getQuand());

								CalendarEvent calendarEvent = new CalendarEvent();
								calendarEvent.setAttribute("eventId",
										String.valueOf(record
												.getAttribute("eventId")));
								calendarEvent.setAttribute("markerId", String
										.valueOf(infoPointBean.getMarkerId()));
								// mise à jour de
								// l'evenement
								display.getCalendar().updateEvent(
										calendarEvent,
										infoPointBean.getQuand(),
										infoPointBean.getQuand(),
										infoPointBean.getOu(),
										infoPointBean.getCommentaire());
								display.getCalendar().markForRedraw();
							} else {
								System.out.println("[client] suppression d'un record "
										+ String.valueOf(record
												.getAttribute("eventId"))
										+ "avec markerID : "
										+ infoPointBean.getMarkerId()
										+ ", ou "
										+ infoPointBean.getOu());

								CalendarEvent calendarEvent = new CalendarEvent();
								calendarEvent.setAttribute("eventId",
										String.valueOf(record
												.getAttribute("eventId")));
								calendarEvent.setAttribute("markerId", String
										.valueOf(infoPointBean.getMarkerId()));
								display.getCalendar()
										.removeEvent(calendarEvent);
								display.getCalendar().markForRedraw();
							}
						}
						display.getCalendrierLayout().redraw();
						display.getCalendrierLayout().markForRedraw();

					}

					private Record getRecord(Long markerId) {
						RecordList recordList = display.getCalendar()
								.getRecordList();
						if (recordList == null) {
							return null;
						}
						Record[] array = recordList.toArray();
						for (Record record : array) {
							if (record.getAttribute("markerId") != null
									&& record.getAttribute("markerId").equals(
											String.valueOf(markerId))) {
								return record;
							}
						}
						return null;

					}

					private void reloadQuand(ProjetBean projetBean) {
						infoService.findAllByProjetId(projetBean.getProjetId(),
								new AsyncCallback<List<InfoPointBean>>() {

									@Override
									public void onSuccess(
											List<InfoPointBean> result) {

										for (InfoPointBean infoPointBean : result) {
											loadQuand(infoPointBean);
										}
									}

									@Override
									public void onFailure(Throwable caught) {
										System.out.println("probleme : "
												+ caught);

									}
								});

					}

				});

	}
}
